package pers.xiaojun.boot.module.infra.controller.config;

import cn.hutool.core.bean.BeanUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import pers.xiaojun.boot.common.pojo.CommonResult;
import pers.xiaojun.boot.common.pojo.PageResult;
import pers.xiaojun.boot.common.util.BeanUtils;
import pers.xiaojun.boot.excel.util.ExcelUtils;
import pers.xiaojun.boot.module.infra.controller.config.vo.ConfigQueryReqVO;
import pers.xiaojun.boot.module.infra.controller.config.vo.ConfigRespVO;
import pers.xiaojun.boot.module.infra.controller.config.vo.ConfigSaveReqVO;
import pers.xiaojun.boot.module.infra.service.config.ConfigService;
import pers.xiaojun.boot.mybatis.core.convert.PageConvert;
import pers.xiaojun.boot.web.core.annotation.AdminApi;

import java.io.IOException;
import java.util.List;

/**
 * 参数配置控制层
 *
 * @author xiaojun
 * @since 2025-11-09
 */
@AdminApi
@Tag(name = "参数配置")
@RestController
@RequestMapping("/infra/config")
@RequiredArgsConstructor
public class ConfigController {

    private final ConfigService configService;

    @Operation(summary = "创建参数")
    @PostMapping
    @PreAuthorize("@ss.hasPermission('infra:config:create')")
    public CommonResult<?> createConfig(@Valid @RequestBody ConfigSaveReqVO createVO) {
        return CommonResult.success(configService.saveConfig(createVO).getId());
    }

    @Operation(summary = "更新参数")
    @PutMapping("/{id}")
    @PreAuthorize("@ss.hasPermission('infra:config:update')")
    @Parameter(name = "id", description = "参数Id", required = true, example = "1")
    public CommonResult<?> updateConfig(@PathVariable("id") Long configId, @Valid @RequestBody ConfigSaveReqVO updateVO) {
        updateVO.setId(configId);
        return CommonResult.success(configService.updateConfig(updateVO).getId());
    }

    @Operation(summary = "删除参数")
    @DeleteMapping("/{id}")
    @PreAuthorize("@ss.hasPermission('infra:config:delete')")
    @Parameter(name = "id", description = "参数Id", required = true, example = "1")
    public CommonResult<?> deleteConfig(@PathVariable("id") Long configId) {
        configService.removeConfigById(configId);
        return CommonResult.success();
    }

    @Operation(summary = "删除参数")
    @DeleteMapping("/batch/{ids}")
    @PreAuthorize("@ss.hasPermission('infra:config:delete')")
    @Parameter(name = "ids", description = "参数Id列表", required = true, example = "1,2,3")
    public CommonResult<?> deleteConfig(@PathVariable("ids") List<Long> configId) {
        configService.removeConfigByIds(configId);
        return CommonResult.success();
    }

    @Operation(summary = "获取参数信息")
    @GetMapping("/{id}")
    @PreAuthorize("@ss.hasPermission('infra:config:query')")
    @Parameter(name = "id", description = "参数Id", required = true, example = "1")
    public CommonResult<ConfigRespVO> getConfig(@PathVariable("id") Long configId) {
        return CommonResult.success(BeanUtil.toBean(configService.getConfigById(configId), ConfigRespVO.class));
    }

    @Operation(summary = "获取参数分页")
    @GetMapping("/page")
    @PreAuthorize("@ss.hasPermission('infra:config:query')")
    public CommonResult<PageResult<ConfigRespVO>> getConfigPage(@Valid ConfigQueryReqVO queryVO) {
        return CommonResult.success(PageConvert.INSTANCE.toPageResult(configService.listConfigsPage(queryVO), ConfigRespVO.class));
    }

    @Operation(summary = "导出参数数据")
    @GetMapping("/export-excel")
    @PreAuthorize("@ss.hasPermission('infra:config:export')")
    public void exportConfig(HttpServletResponse response) throws IOException {
        ExcelUtils.write(
                response,
                ExcelUtils.toXlsxFilename("参数配置"),
                "参数配置",
                ConfigRespVO.class,
                BeanUtils.toBeans(configService.list(), ConfigRespVO.class)
        );
    }

}
